home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / mips / include / asm / mach-generic / ide.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  3.8 KB  |  139 lines

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994-1996  Linus Torvalds & authors
  7.  *
  8.  * Copied from i386; many of the especially older MIPS or ISA-based platforms
  9.  * are basically identical.  Using this file probably implies i8259 PIC
  10.  * support in a system but the very least interrupt numbers 0 - 15 need to
  11.  * be put aside for legacy devices.
  12.  */
  13. #ifndef __ASM_MACH_GENERIC_IDE_H
  14. #define __ASM_MACH_GENERIC_IDE_H
  15.  
  16. #ifdef __KERNEL__
  17.  
  18. #include <linux/pci.h>
  19. #include <linux/stddef.h>
  20. #include <asm/processor.h>
  21.  
  22. /* MIPS port and memory-mapped I/O string operations.  */
  23. static inline void __ide_flush_prologue(void)
  24. {
  25. #ifdef CONFIG_SMP
  26.     if (cpu_has_dc_aliases)
  27.         preempt_disable();
  28. #endif
  29. }
  30.  
  31. static inline void __ide_flush_epilogue(void)
  32. {
  33. #ifdef CONFIG_SMP
  34.     if (cpu_has_dc_aliases)
  35.         preempt_enable();
  36. #endif
  37. }
  38.  
  39. static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
  40. {
  41.     if (cpu_has_dc_aliases) {
  42.         unsigned long end = addr + size;
  43.  
  44.         while (addr < end) {
  45.             local_flush_data_cache_page((void *)addr);
  46.             addr += PAGE_SIZE;
  47.         }
  48.     }
  49. }
  50.  
  51. /*
  52.  * insw() and gang might be called with interrupts disabled, so we can't
  53.  * send IPIs for flushing due to the potencial of deadlocks, see the comment
  54.  * above smp_call_function() in arch/mips/kernel/smp.c.  We work around the
  55.  * problem by disabling preemption so we know we actually perform the flush
  56.  * on the processor that actually has the lines to be flushed which hopefully
  57.  * is even better for performance anyway.
  58.  */
  59. static inline void __ide_insw(unsigned long port, void *addr,
  60.     unsigned int count)
  61. {
  62.     __ide_flush_prologue();
  63.     insw(port, addr, count);
  64.     __ide_flush_dcache_range((unsigned long)addr, count * 2);
  65.     __ide_flush_epilogue();
  66. }
  67.  
  68. static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
  69. {
  70.     __ide_flush_prologue();
  71.     insl(port, addr, count);
  72.     __ide_flush_dcache_range((unsigned long)addr, count * 4);
  73.     __ide_flush_epilogue();
  74. }
  75.  
  76. static inline void __ide_outsw(unsigned long port, const void *addr,
  77.     unsigned long count)
  78. {
  79.     __ide_flush_prologue();
  80.     outsw(port, addr, count);
  81.     __ide_flush_dcache_range((unsigned long)addr, count * 2);
  82.     __ide_flush_epilogue();
  83. }
  84.  
  85. static inline void __ide_outsl(unsigned long port, const void *addr,
  86.     unsigned long count)
  87. {
  88.     __ide_flush_prologue();
  89.     outsl(port, addr, count);
  90.     __ide_flush_dcache_range((unsigned long)addr, count * 4);
  91.     __ide_flush_epilogue();
  92. }
  93.  
  94. static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
  95. {
  96.     __ide_flush_prologue();
  97.     readsw(port, addr, count);
  98.     __ide_flush_dcache_range((unsigned long)addr, count * 2);
  99.     __ide_flush_epilogue();
  100. }
  101.  
  102. static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
  103. {
  104.     __ide_flush_prologue();
  105.     readsl(port, addr, count);
  106.     __ide_flush_dcache_range((unsigned long)addr, count * 4);
  107.     __ide_flush_epilogue();
  108. }
  109.  
  110. static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
  111. {
  112.     __ide_flush_prologue();
  113.     writesw(port, addr, count);
  114.     __ide_flush_dcache_range((unsigned long)addr, count * 2);
  115.     __ide_flush_epilogue();
  116. }
  117.  
  118. static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count)
  119. {
  120.     __ide_flush_prologue();
  121.     writesl(port, addr, count);
  122.     __ide_flush_dcache_range((unsigned long)addr, count * 4);
  123.     __ide_flush_epilogue();
  124. }
  125.  
  126. /* ide_insw calls insw, not __ide_insw.  Why? */
  127. #undef insw
  128. #undef insl
  129. #undef outsw
  130. #undef outsl
  131. #define insw(port, addr, count) __ide_insw(port, addr, count)
  132. #define insl(port, addr, count) __ide_insl(port, addr, count)
  133. #define outsw(port, addr, count) __ide_outsw(port, addr, count)
  134. #define outsl(port, addr, count) __ide_outsl(port, addr, count)
  135.  
  136. #endif /* __KERNEL__ */
  137.  
  138. #endif /* __ASM_MACH_GENERIC_IDE_H */
  139.